/** @file
	@brief Editor pin definitions.
	*/
#ifndef PRYN_EDITOR_PIN_H
#define PRYN_EDITOR_PIN_H

typedef struct PrynEditorPin PrynEditorPin; /// Editor information for a pin.

#include <pryn/editor/board.h>
#include <pryn/editor/component.h>
#include <pryn/editor/path.h>

#include <pryn/pin.h>
#include <pryn/vector.h>

/** @defgroup PrynEditorPin PrynEditorPin C API
	@{
	@}
*/

#if __cplusplus
extern "C" {
#endif

/** @addtogroup PrynEditorPin */
/** @{ */

PrynEditorImport (PrynResult, prynEditorPinFrom, (PrynEditorPin **editor, PrynEditorComponent *component, PrynPin *pin))
	/**< @brief Return the editor pin data for a pin.

	@param[out] editor Written with the editor pin or 0 on failure.
	@param component The component the pin is attached to.
	@param pin The pin to retrieve information for.
	@returns #PrynResultSuccess or an error code; see #PrynResult. */

PrynEditorImport (PrynResult, prynEditorPinUpdateRoute, (PrynEditorPin *editor))
	/**< @brief Update the editor pin route.

	If the pin is not connected, the route is merely deleted.

	@param editor The editor pin to update.
	@returns #PrynResultSuccess on success, or an error code; see #PrynResult. */
	
/** @} */ // (addtogroup PrynEditorPin)

#if __cplusplus
}
#endif

#ifdef PrynEditorInternalStructs
/** Editor information for a pin. This is associated to the pin using the editor board as the key for a tag. This is normally returned from #prynEditorPin or using #PrynEditorPin::From in C++.

	@ingroup PrynEditorPin */
struct PrynEditorPin
{
#ifdef PrynEditorInternal
/** @name Internal fields
	These fields are not normally visible to clients, and it is recommended not to use them to maximise binary compatibility. To make them available, define PrynEditorInternal.
	@{ */

	PrynEditorComponent *component; ///< Component editor.
	PrynEditorBoard *board; ///< The board this pin is on.
	PrynPin *pin; ///< The pin this is related to.
	int x; ///< Horizontal location of the pin on the board. Whenever the component moves, this is changed.
	int y; ///< Vertical location of the pin on the board.
	PrynEditorPathRoute route; ///< Routing for this pin. Only output pins have routes.

/** @} */
#endif /* PrynEditorInternal */

#if __cplusplus
	static inline PrynEditorPin *From (PrynEditorComponent *component, PrynPin *pin) { PrynEditorPin *result; prynEditorPinFrom (&result, component, pin); return result; }
		/**< @brief Return the editor pin data for a pin.

		@param component The component the pin is attached to.
		@param pin The pin to retrieve information for.
		@returns The editor pin. */

	static inline PrynEditorPin *From (PrynEditorBoard *board, PrynPin *pin) { PrynComponent *component; PrynEditorComponent *editor; prynPinComponent (pin, &component); prynEditorComponentFrom (&editor, board, component); return From (editor, pin); }
		/**< @brief Return the editor pin data for a pin.

		@param board The board the pin's component should be on.
		@param pin The pin to retrieve information for.
		@returns The editor pin. */

	inline void updateRoute () { prynEditorPinUpdateRoute (this); }
		/**< @brief Update the editor pin route.

		If the pin is not connected, the route is merely deleted. */

#endif /* __cplusplus */
};
#endif /* PrynEditorStructs */

#define prynEditorPinSize 8 ///< Size of a pin box.
#define prynEditorPinSizeHalf (prynEditorPinSize / 2) ///< Half a pin size.
#define prynEditorPinStride (prynEditorPinSize + 2) ///< Total width of a pin.

#endif /* PRYN_EDITOR_PIN_H */
